import re, constants

from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from .models import User


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    """自定义载荷信息"""

    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        # 添加自定义载荷内容
        if hasattr(user, 'avatar'):
            token['avatar'] = user.avatar.url if user.avatar else ""
        if hasattr(user, 'nickname'):
            token['nickname'] = user.nickname
        if hasattr(user, 'money'):
            token['money'] = float(user.money)
        if hasattr(user, 'credit'):
            token['credit'] = user.credit

        return token




class UserRegistrationModelSerializer(serializers.ModelSerializer):
    """用户注册序列化器"""
    re_password = serializers.CharField(write_only=True, required=True)
    sms_code = serializers.CharField(write_only=True, required=True)

    # access_token = serializers.CharField(write_only=True, required=True)
    # refresh_token = serializers.CharField(write_only=True, required=True)

    class Meta:
        model = User
        fields = ['mobile', 'password', 're_password', 'sms_code']
        extra_kwargs = {
            "mobile": {
                "required": True, "write_only": True
            },
            "password": {
                "required": True, "write_only": True, "min_length": 6, "max_length": 16,
            },
        }

    def validate(self, data):
        """验证客户端数据"""
        # 手机号格式验证
        mobile = data.get("mobile", None)
        if not re.match(r"^1[3-9]\d{9}$", mobile):
            raise serializers.ValidationError(detail="手机号格式不正确！嘎嘎嘎", code="mobile")

        # 密码和确认密码
        password = data.get("password")
        re_password = data.get("re_password")
        if password != re_password:
            raise serializers.ValidationError(detail="密码和确认密码不一致！hhh", code="password")

        # 手机号是否已注册
        exist = User.objects.filter(mobile=mobile).exists()
        if exist:
            raise serializers.ValidationError(detail="手机号已注册！jjj", code="mobile")

        # 验证短信验证码
        # 从redis中提取短信
        redis = get_redis_connection("sms_code")  # 连接redis对象 参数是缓存库的别名
        code = redis.get(f"sms_{mobile}")
        if code is None:
            """获取不到验证码，则表示验证码已经过期了"""
            raise serializers.ValidationError(detail="验证码失效或已过期！11", code="sms_code")

        # 从redis提取的数据，字符串都是bytes类型，所以decode
        if code.decode() != data.get("sms_code"):
            raise serializers.ValidationError(detail="短信验证码错误！嘎嘎嘎哈哈", code="sms_code")
        print(f"code={code.decode()}, sms_code={data.get('sms_code')}")
        # 删除掉redis中的短信，后续不管用户是否注册成功，至少当前这条短信验证码已经没有用处了
        redis.delete(f"sms_{mobile}")

        return data

    def create(self, validated_data):
        """保存用户信息，完成注册"""
        mobile = validated_data.get("mobile")
        password = validated_data.get("password")

        # create_user保存数据，密码会自动加密
        user = User.objects.create_user(
            username=mobile,
            mobile=mobile,
            avatar=constants.DEFAULT_USER_AVATAR,
            password=password,
        )

        return user
